package model;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.ArrayList;


/**
 * Model class. Handles pretty much all the storage for the game.
 * @author Tim Cocu
 * @version 1.0
 */
public class Model 
{
	private World world;
	private double dTranslateX, dTranslateY;
	private int iScreenWidth, iScreenHeight;
	private Point2D latestMousePos;
	private ArrayList<String> chatHistory;
	private String latestMessage;
	private char[] allowedChars = { '/', ' ', '0', '1', '2', '3' , '4', '5', '6', '7', '8', '9', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

	
	/**
	 * Constructor for instances of the model type.
	 * Defines a new 'Model' object.
	 */
	public Model(int iScreenWidth, int iScreenHeight)
	{
		this.iScreenWidth = iScreenWidth;
		this.iScreenHeight = iScreenHeight;
		
		chatHistory = new ArrayList<String>();		
		latestMessage = "";
		
		latestMousePos = new Point2D.Double();
	}
	
	private void handleCommand(String strCommand)
	{
		System.out.println(strCommand);
		String[] splitCommands = strCommand.split(" ");

		if(splitCommands[0].toUpperCase().equals("/AA"))
		{
			if(splitCommands.length == 1)
			{
				Settings.AntiAliasing = !Settings.AntiAliasing;
				chatHistory.add("AA set to: " + Settings.AntiAliasing);
				return;
			}
			if(splitCommands[1].equals("ON"))
			{
				Settings.AntiAliasing = true;
			}
			if(splitCommands[1].equals("OFF"))
			{
				Settings.AntiAliasing = false;
			}
			
			chatHistory.add("AA set to: " + Settings.AntiAliasing);
		}
		
		if(splitCommands[0].toUpperCase().equals("/TP"))
		{
			if(splitCommands.length == 1)
			{
				world.getPlayer().setPosition(0.0, 0.0);
				chatHistory.add("TELEPORTED TO [0, 0]");
			}
			if(splitCommands.length == 3)
			{
				double dTeleportX = Integer.parseInt(splitCommands[1]);
				double dTeleportY = Integer.parseInt(splitCommands[2]);
				world.getPlayer().setPosition(dTeleportX, dTeleportY);
				chatHistory.add("TELEPORTED TO [" + (int) dTeleportX + "," + (int) dTeleportY + "]");
			}
		}
	}
	
	public void notifyEndOfMessage()
	{
		if(!latestMessage.startsWith("/"))
		{
			chatHistory.add(latestMessage);
		}
		else
		{
			handleCommand(latestMessage);
		}
		latestMessage = "";
	}
	
	public String getLatestMessage()
	{
		return latestMessage;
	}
	
	public void addCharacter(char character)
	{
		for(int iIndex = 0; iIndex < allowedChars.length; iIndex++)
		{
			if(allowedChars[iIndex] == character)
			{
				latestMessage += character;
				return;
			}
		}
		
		System.out.println("CHAR NOT FOUND");
	}
	
	/**
	 * Accesor method for the screen width
	 * @return Screen width
	 */
	public int getScreenWidth()
	{
		return iScreenWidth;
	}
	
	/**'
	 * Accessor method for the screen height
	 * @return Screen height
	 */
	public int getScreenHeight()
	{
		return iScreenHeight;
	}
	
	/**
	 * Method for returning the X the map is translated over.
	 * @return X translation.
	 */
	public double getTranslateX()
	{
		return (iScreenWidth / 2) - (world.getPlayer().getWidth() / 2) - world.getPlayer().getPosition().x;
	}
	
	/**
	 * Method for returning the Y the map is translated over.
	 * @return Y translation.
	 */
	public double getTranslateY()
	{
		return (iScreenHeight / 2) - (world.getPlayer().getHeight()) - world.getPlayer().getPosition().y;
	}

	/**
	 * Mutator method that defines (re)setting the world.
	 * @param newWorld The new world.
	 */
	public void setWorld(World newWorld)
	{
		this.world = newWorld;
	}
	
	public ArrayList<String> getChatHistory()
	{
		return chatHistory;
	}
	
	/**
	 * Accessor method that defines getting the world.
	 * @return Current world.
	 */
	public World getWorld()
	{
		return world;
	}
	
	public Point2D getLatestMousePos()
	{
		return latestMousePos;
	}

	/**
	 * Set the latest mouse position.
	 * @param point Latest mouse position.
	 */
	public void setLatestMousePos(Point point) 
	{
		latestMousePos = point;
	}

	public void removeChar() 
	{
		if(latestMessage.length() > 0)
		{
			char[] chArr = latestMessage.toCharArray();
			latestMessage = "";
			
			for(int iIndex = 0; iIndex < chArr.length - 1; iIndex++)
				latestMessage += chArr[iIndex];
		}
	}
}
